import requests
from datetime import datetime, timedelta
from vfeeds import DataFeed


class BinanceSpotFeed(DataFeed):
    baseUrl = "https://data-api.binance.vision/api/v3"
    intervalMaps = {
        "1min": "1m", "5min": "5m", "15min": "15m", "30min": "30m", "H": "1h",
        "D": "1d", "W": "1w", "M": "1M"
    }

    @staticmethod
    def to_millisecond(dt):
        return int(dt.timestamp() * 1000)

    @staticmethod
    def to_datetime_string(timestamp, interval):
        dt = datetime.fromtimestamp(timestamp / 1000)
        if interval in ("D", "W", "M"):
            dt = dt - timedelta(hours=8)
        return dt.strftime("%Y-%m-%d %H:%M:%S")

    def get_detail(self):
        result = list()
        json_data = requests.get(self.baseUrl + "/exchangeInfo").json()
        for item in json_data["symbols"]:
            if item["status"] == "TRADING":
                result.append({
                    "title": item["baseAsset"] + "/" + item["quoteAsset"],
                    "symbol": item["symbol"],
                    "price_tick": float(item["filters"][0]["tickSize"]),
                    "min_volume": float(item["filters"][1]["stepSize"])
                })
        return result

    def get_history(self, symbol, interval, start, end, **kwargs):
        result = list()
        json_data = requests.get(self.baseUrl + "/klines", params={
            "symbol": symbol,
            "interval": self.intervalMaps[interval],
            "startTime": self.to_millisecond(start),
            "endTime": self.to_millisecond(end),
            "limit": 1000
        }).json()
        for item in json_data:
            result.append({
                "datetime": self.to_datetime_string(item[0], interval),
                "open": float(item[1]),
                "high": float(item[2]),
                "low": float(item[3]),
                "close": float(item[4]),
                "volume": float(item[5]),
                "amount": float(item[7]),
            })
        return result

    def get_ticker(self, symbol):
        json_data = requests.get(self.baseUrl + "/ticker/24hr", params=dict(symbol=symbol)).json()
        return {
            "open": float(json_data["openPrice"]),
            "high": float(json_data["highPrice"]),
            "low": float(json_data["lowPrice"]),
            "close": float(json_data["lastPrice"]),
            "pre_close": float(json_data["prevClosePrice"]),
            "volume": float(json_data["volume"]),
            "amount": float(json_data["quoteVolume"]),
            "ask": float(json_data["askPrice"]),
            "bid": float(json_data["bidPrice"])
        }


__all__ = [BinanceSpotFeed]
